import React, { Component } from 'react'
import PropTypes from 'prop-types'
class Counter extends Component {
  // constructor作用：1.初始化state  2.绑定成员函数的this环境
  constructor (props) {
    super(props)
    // 构造函数中通过props获得传入的prop的值
    this.state = {
      count: props.initValue
    }
    this.onClickIncrementButton = this.onClickIncrementButton.bind(this)
    this.onClickDecrementButton = this.onClickDecrementButton.bind(this)
  }
  onClickIncrementButton () {
    this.updateCount(true)
  }
  onClickDecrementButton () {
    this.updateCount(false)
  }
  updateCount (isIncrement) {
    const previousValue = this.state.count
    const newValue = isIncrement ? previousValue + 1 : previousValue - 1
    this.setState({
      count: newValue
    })
    this.props.onUpdate(newValue, previousValue)
  }
  // 组件装载的生命周期
  componentWillMount() { // 浏览器端服务端都可以调用
    console.log('enter componentWillMount', this.props.caption)
  }
  componentDidMount () { // 只能浏览器端调用，服务端不调用。可以在这里获取DOM
    console.log('enter componentDidMount', this.props.caption)
  }
  // 组件更新过程的生命周期
  componentWillReceiveProps () {
    //只要父组件的render函数呗调用，不管传给子组件的props有无改变，都会触发
    console.log('enter componentWillReceiveProps', this.props.caption)
  }
  shouldComponentUpdate (nextProps, nextState) { 
    // 返回一个布尔值，告诉React库这个组件在这次更新过程中是否要继续
    // return true
    // nextProps/nextState: 更新后的props/state
    return (nextProps.count !== this.props.count) || (nextState.count !== this.state.count)
  }
  componentWillUpdate () { // 在render执行之前

  }
  componentDidUpdate () { // 在render执行之后，无论在服务端还是客户端，都会执行

  }
  // 卸载过程
  componentWillUnmount() { // react组件要从DOM树上删除之前调用，做清理工作

  }
  // render函数是react组件中最重要的函数，一个React组件可以忽略其他所有函数都不实现，但是一定要实现render函数，因为所有React组件的父类React.Component类除render之外的生命周期函数都有默认实现
  render () {
    console.log('enter render', this.props.caption)
    // 其他函数中通过this.props访问传入的prop的值
    const {caption} = this.props
    return (
      <div>
        <button onClick={this.onClickIncrementButton}>+</button>
        <button onClick={this.onClickDecrementButton}>-</button>
        <span>{caption} Count: {this.state.count}</span>
      </div>
    )
  }
}
// ES6定义的组件类中，可以通过类的propTypes属性来定义prop规格
Counter.propTypes = {
  caption: PropTypes.string,
  initValue: PropTypes.number.isRequired,
  onUpdate: PropTypes.func.isRequired
}
Counter.defaultProps = {
  caption: 'default'
}
export default Counter
